package net.qunzhi.modules.cms.service.impl;

import net.qunzhi.common.exception.RRException;
import net.qunzhi.common.utils.*;
import net.qunzhi.modules.app.query.CopyDataQuery;
import net.qunzhi.modules.cms.dao.TbCumulativeFlowDao;
import net.qunzhi.modules.cms.dto.UndoCopyDto;
import net.qunzhi.modules.cms.entity.TbEquipmentEntity;
import net.qunzhi.modules.cms.query.DailyRecordListQuery;
import net.qunzhi.modules.cms.service.TbEquipmentService;
import net.qunzhi.modules.cms.vo.DataResultVO;
import net.qunzhi.modules.cms.vo.UndoCopyDataVO;
import net.qunzhi.modules.cms.vo.UndoCopyVO;
import net.qunzhi.modules.sys.entity.SysUserEntity;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import net.qunzhi.modules.cms.dao.TbCopyFlowDataDao;
import net.qunzhi.modules.cms.entity.TbCopyFlowDataEntity;
import net.qunzhi.modules.cms.service.TbCopyFlowDataService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


@Service("tbCopyFlowDataService")
public class TbCopyFlowDataServiceImpl extends ServiceImpl<TbCopyFlowDataDao, TbCopyFlowDataEntity> implements TbCopyFlowDataService {

    @Autowired private TbEquipmentService equipmentService;
    @Autowired private TbCumulativeFlowDao cumulativeFlowDao;

    @Override
    public PageUtils queryPage(CopyDataQuery query) {
        IPage<TbCopyFlowDataEntity> page = this.page(
                new Query<TbCopyFlowDataEntity>().getPage(query),
                new QueryWrapper<TbCopyFlowDataEntity>()
                        .eq(null!=query.getAreaId(), "area_id", query.getAreaId())
                        .le(null!=query.getEndDate(), "DATE(date)", query.getEndDate())
                        .ge(null!=query.getStartDate(), "DATE(date)", query.getStartDate())
                        .orderByDesc("date")
        );

        return new PageUtils(page);
    }

    @Override
    public List<DataResultVO> getDataResult(List<DataResultVO> collect, DailyRecordListQuery query) {
        List<Integer> idList = collect.stream().map(DataResultVO::getId).collect(Collectors.toList());
        Integer[] idArr = idList.toArray(new Integer[idList.size()]);
        return baseMapper.getDataResult(idArr, query);
    }

    @Override
    @Transactional
    public void importExcel(String fileName, MultipartFile file) throws Exception {
        var sheet = ExcelReader.getType(fileName,file);
        try {
            SysUserEntity user = ShiroUtils.getUserEntity();
            for (int r = 1; r <= sheet.getLastRowNum(); r++) {
                Row row = sheet.getRow(r);
                if (row == null || row.getLastCellNum() == -1) {
                    continue;
                }
                List<String> list = new ArrayList<>();
                int i=0;
                String dateTime = null;
                for (Cell cell : row) {
                    if (i==1) {// 时间格式另外处理
                        dateTime = DateUtils.format(row.getCell(1).getDateCellValue(), DateUtils.DATE_TIME_PATTERN);
                    } else {
                        var value = ExcelReader.getValue(cell);
                        list.add(value.trim());
                    }
                    i++;
                }
                saveContent(list,dateTime);
            }
        } catch (Exception e) {
            throw new RRException("导入失败，请核查后重新导入。");
        }
    }

    @Override
    public UndoCopyVO getUndoCopyData(String startDate, String endDate) {
        List<String> dateList = DateUtils.getBetweenDate(startDate, endDate);
        dateList.add(DateUtils.stringToLocalDate(startDate).plusDays(-1).toString());
        UndoCopyVO vo = new UndoCopyVO();
        ArrayList<UndoCopyDto> copyDtos = new ArrayList<>();
        ArrayList<UndoCopyDto> cumulativeDtos = new ArrayList<>();
        dateList.forEach(date -> {
            List<Integer> copyIds = this.baseMapper.getUndoDataIdsByDate(date);
            if (CollectionUtils.isNotEmpty(copyIds)) {
                UndoCopyDto dto = new UndoCopyDto().setIds(copyIds).setDate(date);
                copyDtos.add(dto);
            }
            List<Integer> cumulativeIds = cumulativeFlowDao.getUndoIdsByDate(date);
            if (CollectionUtils.isNotEmpty(cumulativeIds)) {
                UndoCopyDto dto = new UndoCopyDto().setIds(cumulativeIds).setDate(date);
                cumulativeDtos.add(dto);
            }
        });
        vo.setCopyList(copyDtos);
        vo.setCumulativeList(cumulativeDtos);
        return vo;
    }

    @Override
    public void getCopyFlowDataTask() {

    }

    private void saveContent(List<String> list, String dateTime) {
        String area = list.get(0);
        Optional.ofNullable(
                equipmentService.getOne(new QueryWrapper<TbEquipmentEntity>().eq("flow_meter_name", area))
        ).ifPresent(data -> {
            TbCopyFlowDataEntity copyFlowDataEntity = new TbCopyFlowDataEntity()
                    .setArea(area)
                    .setAreaId(data.getId())
                    .setPositiveFlow(Float.valueOf(list.get(1)))
                    .setNegativeFlow(Float.valueOf(list.get(2)))
                    .setInstantFlow(Float.valueOf(list.get(3)))
                    .setDate(LocalDateUtils.stringToDateTime(dateTime))
                    ;
            this.save(copyFlowDataEntity);
        });
    }

}